package org.jflame.context.security.mask.fastjson;

import org.jflame.context.security.mask.Mask;
import org.jflame.context.security.mask.MaskHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.fastjson.serializer.BeanContext;
import com.alibaba.fastjson.serializer.ContextValueFilter;

/**
 * fastjson脱敏注解序列化处理器
 * <p>
 * 使用方法: <br>
 * 1.在类上设置<code>@JSONType(serialzeFilters =MaskedValueFilter.class)</code><br>
 * 2.在需要字段上加@Mask注解,设置脱敏规则
 * 
 * @author charles.zhang
 * @see Mask
 */
public class MaskedValueFilter implements ContextValueFilter {

    private static final Map<String,MaskHandler> MASK_HANDLER_CACHE = new ConcurrentHashMap<>();

    @Override
    public Object process(BeanContext context, Object object, String name, Object value) {
        if (value instanceof String strValue) {
            if (strValue.isBlank()) {
                return strValue;
            }
            final Mask annation = context.getAnnation(Mask.class);
            if (annation != null) {
                MaskHandler converter = MASK_HANDLER_CACHE.computeIfAbsent(key(context.getBeanClass(), name),
                        m -> MaskHandler.build(annation));
                return converter.apply(strValue);
            }
        }
        return value;
    }

    protected String key(Class<?> objectClass, String name) {
        return objectClass.getName() + "." + name;
    }

    /* 
     *  MaskedSerializer实现ObjectSerializer接口,在@JSONType(serializeUsing=MaskedSerializer.class)注解中使用
     *  * @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
            throws IOException {
        InnerMaskedSerializer innerSerializer = new InnerMaskedSerializer(object.getClass());
        innerSerializer.write(serializer, object, fieldName, fieldType, features);
    }
    public static class InnerMaskedSerializer extends JavaBeanSerializer {
    
        public InnerMaskedSerializer(Class<?> beanType) {
            super(beanType);
        }
    
        protected Object processValue(JSONSerializer jsonBeanDeser, //
                BeanContext beanContext, Object object, //
                String key, //
                Object propertyValue, //
                int features) {
            Object value = super.processValue(jsonBeanDeser, beanContext, object, key, propertyValue, features);
            if (value instanceof String strValue) {
                Mask mastAnnot = beanContext.getAnnation(Mask.class);
                if (mastAnnot != null) {
                    MaskHandler converter = MASK_HANDLER_CACHE.computeIfAbsent(key(beanContext, object, key, mastAnnot),
                            m -> MaskHandler.build(mastAnnot));
                    return converter.apply(strValue);
                }
            }
            return value;
        }
    }
    */

}
